package com.dingreading.cloud.common.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class DateUtil {

    public static final String DEFAULT_DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String DEFAULT_LASTDATETIME_FORMAT = "yyyy-MM-dd 23:59:59";
    public static final String DEFAULT_BGNDATETIME_FORMAT = "yyyy-MM-dd 00:00:00";
    public static final String DEFAULT_DATETIME24_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";
    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
    public static final String DEFAULT_DATE_FORMAT_SLASH = "yyyy/MM/dd";
    public static final String YEAR_MONTH_FORMAT = "yyyy/MM";
    public static final String DEFAULT_YEAR_MONTH_FORMAT1 = "yyyy-MM";
    public static final String DEFAULT_DATEFULLDATE_FORMAT = "yyyyMMdd";
    public static final String DEFAULT_YEAR_MONTH_FORMAT = "yyyyMM";
    public static final String DEFAULT_YEAR_FORMAT = "yyyy";
    public static final String DEFAULT_MONTH_FORMAT = "MM";
    public static final String DEFAULT_Day_FORMAT = "dd";
    private static final String DEFAULT_DATEMOBAN_FORMAT = "MM-dd HH:mm";
    private static final String DEFAULT_DATEFULLTIME_FORMAT = "yyyyMMddHHmmss";
    private static final long MILLISECONDS_A_DAY = 24 * 3600 * 1000;
    private static final long MILLISECONDS_A_HOUR = 3600 * 1000;
    private static final long MILLISECONDS_A_second = 1000;
    private static final String MILLISECOND_FORMAT = "yyyyMMddHHmmssSSS";
    //验证日期字符串，有效日期范围1900-1-1到2099-12-31
    private static final Pattern pattern = Pattern
            .compile("(?:(?:19|20)\\d{2})-(?:0?[1-9]|1[0-2])-(?:0?[1-9]|[12][0-9]|3[01])");
    private static final Logger logger = LoggerFactory.getLogger(DateUtil.class);

    /**
     * @return String
     * @Description:获取当前时间的30天后的时间
     */
    public static Date getPreMonth() {
        Date now = addDays(new Date(), 30);
        SimpleDateFormat format = new SimpleDateFormat(DEFAULT_DATETIME_FORMAT);
        Date afterMonth = null;
        try {
            afterMonth = format.parse(format.format(now.getTime()));
        } catch (ParseException e) {
            logger.error("解析日期失败:方法,getPreMonth()", e);
        }
        return afterMonth;
    }

    //获取本周的开始时间
    public static Date getBeginDayOfWeek() {
        Date date = new Date();
        if (date == null) {
            return null;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayofweek == 1) {
            dayofweek += 7;
        }
        cal.add(Calendar.DATE, 2 - dayofweek);
        return getDayStartTime(cal.getTime());
    }

    //获取本周的结束时间
    public static Date getEndDayOfWeek() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getBeginDayOfWeek());
        cal.add(Calendar.DAY_OF_WEEK, 6);
        Date weekEndSta = cal.getTime();
        return getDayEndTime(weekEndSta);
    }

    //获取某个日期的开始时间
    public static Timestamp getDayStartTime(Date d) {
        Calendar calendar = Calendar.getInstance();
        if (null != d) calendar.setTime(d);
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return new Timestamp(calendar.getTimeInMillis());
    }

    //获取某个日期的结束时间
    public static Timestamp getDayEndTime(Date d) {
        Calendar calendar = Calendar.getInstance();
        if (null != d) calendar.setTime(d);
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return new Timestamp(calendar.getTimeInMillis());
    }

    /**
     * @return String
     * @Description: 将时间转化格式为  yyyy-MM-dd HH:mm:ss 的字符串
     */
    public static String getDefaultTimeStr(Date date) {
        SimpleDateFormat format = new SimpleDateFormat(DEFAULT_DATETIME_FORMAT);
        return format.format(date);
    }

    /**
     * @return String
     * @Description: 将时间转化格式为  MM-dd HH:mm 的字符串
     */
    public static String getDefaultMOBANTimeStr(Date date) {
        SimpleDateFormat format = new SimpleDateFormat(DEFAULT_DATEMOBAN_FORMAT);
        return format.format(date);
    }


    /**
     * @return String
     * @Description: 将时间转化格式为  yyyy-MM-dd 23:59:59 的字符串
     */
    public static String getDefaultLastTimeStr(Date date) {
        SimpleDateFormat format = new SimpleDateFormat(DEFAULT_LASTDATETIME_FORMAT);
        return format.format(date);
    }

    /**
     * @return String
     * @Description: 将时间转化格式为  yyyy-MM-dd 00:00:00的字符串
     */
    public static String getDefaultBGNTimeStr(Date date) {

        SimpleDateFormat format = new SimpleDateFormat(DEFAULT_BGNDATETIME_FORMAT);
        return format.format(date);
    }

    /**
     * 将时间转化格式为  yyyy-MM-dd 的字符串
     *
     * @param date
     * @return
     */
    public static String getDefaultTime2DateStr(Date date) {
        SimpleDateFormat format = new SimpleDateFormat(DEFAULT_DATE_FORMAT);
        return format.format(date);
    }

    /**
     * 将时间转化格式为  yyyy-MM-dd 的字符串
     *
     * @param date
     * @return
     */
    public static String getDefaultDateFulltime(Date date) {
        SimpleDateFormat format = new SimpleDateFormat(DEFAULT_DATEFULLTIME_FORMAT);
        return format.format(date);
    }


    /**
     * 月份运算
     *
     * @param date    时间
     * @param amount  相加或相减的月份
     * @param pattern 时间格式
     * @return
     */
    public static Date gapMonth(Date date, int amount, String pattern) throws ParseException {
        Date endDate = DateUtils.addMonths(date, amount);
        Date overDate = DateUtils.parseDate(DateFormatUtils.format(endDate, pattern), DEFAULT_DATETIME_FORMAT);
        return overDate;
    }

    /**
     * 年份运算
     *
     * @param date    时间
     * @param amount  相加或相减的月份
     * @param pattern 时间格式
     * @return
     */
    public static Date gapYear(Date date, int amount, String pattern) throws ParseException {
        Date endDate = DateUtils.addYears(date, amount);
        Date overDate = DateUtils.parseDate(DateFormatUtils.format(endDate, pattern), DEFAULT_DATETIME_FORMAT);
        return overDate;
    }

    /**
     * 年份运算
     *
     * @param nowTime 时间
     * @param amount  相加或相减的月份
     * @param pattern 时间格式
     * @return
     */
    public static String gapYear(String nowTime, int amount, String pattern) throws ParseException {
        Date date = parseDate(nowTime, pattern);
        Date endDate = DateUtils.addYears(date, amount);
        Date overDate = DateUtils.parseDate(DateFormatUtils.format(endDate, pattern), DEFAULT_DATETIME_FORMAT);
        String endTime = getDefaultTimeStr(overDate);
        return endTime;
    }

    /**
     * 获取精确到秒的时间戳
     *
     * @param date date
     * @return date为空则返回null
     */
    public static String getSecondTimestamp(Date date) {
        if (null != date) {
            return String.valueOf(date.getTime() / 1000);
        }
        return null;
    }

    public static Date parseDate(String s) throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        return format.parse(s);
    }

    public static Date parseDate(String s, String format) throws ParseException {
        if (StringUtils.isBlank(format)) {
            format = DEFAULT_DATE_FORMAT;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.parse(s);
    }

    /**
     * 按 yyyy-MM-dd HH:mm:ss 转换时间
     */
    public static Date parseDateFromStr(String s) throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat(DEFAULT_DATETIME_FORMAT);
        return format.parse(s);
    }

    /**
     * 按 yyyyMMddHHmmss 转换时间
     */
    public static Date parseDateFromStrs(String s) throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat(DEFAULT_DATEFULLTIME_FORMAT);
        return format.parse(s);
    }

    /**
     * 按 yyyy-MM-dd 00:00:00 转换时间
     */
    public static Date parseDayBeginFromStr(String s) throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat(DEFAULT_BGNDATETIME_FORMAT);
        return format.parse(s);
    }

    /**
     * 按 yyyy-MM-dd 23:59:59 转换时间
     */
    public static Date parseDayEndFromStr(String s) throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat(DEFAULT_LASTDATETIME_FORMAT);
        return format.parse(s);
    }

    /**
     * 当前时间加上second秒
     */
    public static Date addSecond(Date date, int second) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.SECOND, second);
        return cal.getTime();
    }

    /**
     * 当前时间加上minute分钟
     */
    public static Date addMinutes(Date date, int minute) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MINUTE, minute);
        return cal.getTime();
    }

    /**
     * 当前时间加上hour小时
     */
    public static Date addHours(Date date, int hours) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.HOUR_OF_DAY, hours);
        return cal.getTime();
    }

    /**
     * 当前时间加上day天
     */
    public static Date addDays(Date date, int days) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DATE, days);
        return cal.getTime();
    }

    /**
     * 当前时间加上week周
     */
    public static Date addWeeks(Date date, int week) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.WEEK_OF_MONTH, week);
        return cal.getTime();
    }

    /**
     * 当前时间加上days月
     */
    public static Date addMonths(Date date, int months) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, months);
        return cal.getTime();
    }


    /**
     * 当前时间加上years年
     */
    public static Date addYears(Date date, int years) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.YEAR, years);
        return cal.getTime();
    }

    /**
     * 获取当前年份
     *
     * @return
     */
    public static int getYear() {
        Calendar cal = Calendar.getInstance();
        return cal.get(Calendar.YEAR);
    }

    /**
     * 获取当前日期年份
     *
     * @return
     */
    public static int getYear(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.YEAR);
    }

    /**
     * 获取当前月
     *
     * @return
     */
    public static int getMonth() {
        Calendar cal = Calendar.getInstance();
        return cal.get(Calendar.MONTH) + 1;
    }

    /**
     * 获取指定月的最小时间
     *
     * @param date
     * @return
     */
    public static Date getMinDateByMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DATE, cal.getActualMinimum(Calendar.DATE));
        return cal.getTime();
    }

    /**
     * 获取指定月的最大时间
     *
     * @param date
     * @return
     */
    public static Date getMaxDateByMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE));
        return cal.getTime();
    }

    /**
     * 获取当前月的最小日期
     *
     * @return
     */
    public static Date getMonthMinDate() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DATE, cal.getActualMinimum(Calendar.DATE));
        return cal.getTime();
    }

    /**
     * 获取当前月的最大日期
     *
     * @return
     */
    public static Date getMonthMaxDate() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE));
        return cal.getTime();
    }

    public static void main(String[] args) {
        Date minDate = getMonthMinDate();
        String min = getDefaultTime2DateStr(minDate);
        System.out.println("min = " + min);
        Date maxDate = getMonthMaxDate();
        String max = getDefaultTime2DateStr(maxDate);
        System.out.println("max = " + max);
    }

    /**
     * 取得某月的的最后一天
     *
     * @param year
     * @param month
     * @return
     */
    public static Date getLastDayOfLastMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);// 年
        cal.set(Calendar.MONTH, month - 1);// 月，因为Calendar里的月是从0开始，所以要减1
        cal.set(Calendar.DATE, 1);// 日，设为一号
        cal.add(Calendar.DATE, -1);// 下一个月减一为本月最后一天
        return cal.getTime();// 获得月末是几号
    }

    /**
     * 获得指定格式的日期时间字符串
     *
     * @param format
     * @return
     */
    public static String datetime(String format) {
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        return formatter.format(new Date());
    }

    /**
     * @return
     * @Description: 获取当天时间最后一秒(毫秒)
     */
    public static Date getEndTime() {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date = getCurrentDate() + " 23:59:59";
        Date time = null;
        try {
            time = formatter.parse(date);
        } catch (ParseException e) {
            logger.error("获取当天时间的结束时间: ", e);
        }
        return time;
    }

    /**
     * 获得指定格式的日期时间字符串
     *
     * @param date
     * @param format
     * @return
     */
    public static String datetime(Date date, String format) {
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        return formatter.format(date);
    }

    /**
     * 获得指定格式的日期时间字符串
     *
     * @param date   日期字符串
     * @param format
     * @return
     */
    public static String datetime(String date, String format) {
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        return formatter.format(date);
    }

    /**
     * 获得指定格式的当前日期字符串
     *
     * @param date
     * @param format
     * @return
     */
    public static String date(Date date, String format) {
        if (date == null) {
            return "";
        }

        return (new SimpleDateFormat(format)).format(date);
    }

    /**
     * 获得指定格式的当前日期字符串
     *
     * @param dateStr
     * @param format
     * @return
     */
    public static String date(String dateStr, String format) {
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        return formatter.format(dateStr);
    }

    /**
     * 获得"yyyy-MM-dd"格式的当前日期字符串
     *
     * @return
     */
    public static String getNowDateStr() {
        return getNowDatetimeStr(DEFAULT_DATE_FORMAT);
    }

    public static String getDateBeforeNDays(String dateStr, int days) {
        if (StringUtils.isBlank(dateStr)) {
            return null; // 或者返回当前日期
        }
        try {
            // 定义日期格式
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT);
            // 解析日期字符串
            LocalDate date = LocalDate.parse(dateStr, formatter);
            // 减去n天
            LocalDate newDate = date.minusDays(days);
            // 转换回字符串
            return newDate.format(formatter);
        } catch (DateTimeParseException e) {
            // 解析异常处理
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获得"yyyy-MM-dd HH:mm:ss"格式的当前日期时间字符串
     *
     * @return
     */
    public static String getNowDatetimeStr() {
        return getNowDatetimeStr(DEFAULT_DATETIME_FORMAT);
    }

    /**
     * 获得"yyyy-MM-dd HH:mm:ss"格式的当前日期时间字符串
     *
     * @return
     */
    public static Date getNowDatetime() {
        return new Date(System.currentTimeMillis());
    }

    /**
     * 获得"yyyyMMddHHmmss"格式的当前日期时间字符串
     *
     * @return
     */
    public static String getNowDateminStr() {
        return getNowDatetimeStr(DEFAULT_DATEFULLTIME_FORMAT);
    }

    /**
     * 将当前时间转成毫秒
     *
     * @return String
     */
    public static String getMillSecondStr() {
        Calendar cal = Calendar.getInstance();
        return datetime(cal.getTime(), MILLISECOND_FORMAT);
    }

    /**
     * 获得当前日期时间字符串
     *
     * @param format 日期格式
     * @return 日期时间字符串
     */
    public static String getNowDatetimeStr(String format) {
        Calendar cal = Calendar.getInstance();
        return datetime(cal.getTime(), format);
    }

    /**
     * 只取当前时间的日期部分，小时、分、秒等字段归零
     */
    public static Date dateOnly(Date date) {
        return new Date(date.getTime() / MILLISECONDS_A_DAY);
    }

    /**
     * 获取某个日期最大时间，yyyy-MM-dd 23:59:59
     *
     * @param date
     * @return
     */
    public static Date dateMaxTime(Date date) {
        Date date1 = dateOnlyExt(date);
        Calendar c = Calendar.getInstance();
        c.setTime(date1);
        c.add(Calendar.DATE, 1);
        c.add(Calendar.SECOND, -1);
        date = c.getTime();
        return date;
    }

    /**
     * 只取当前时间的日期部分，小时、分、秒等字段归零
     */
    public static Date dateOnlyExt(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    /**
     * 只取当前时间的日期部分，小时、分、秒等字段归零
     */
    public static Date dateMinTime(Date date) {
        return dateOnlyExt(date);
    }

    /**
     * 把类似2007-2-2 7:1:8的时间串变为标准的2007-02-02 07:01:08
     *
     * @param dateTimeStr 未校正日期值
     * @return 日期对象
     */
    public static String getStandDateTimeStr(String dateTimeStr) {
        if (dateTimeStr == null || "".equals(dateTimeStr)) {
            return "";
        }

        dateTimeStr = dateTimeStr.replaceAll("\\s+", "|");
        String[] a = dateTimeStr.split("\\|");
        List<String> list = Arrays.asList(a);
        String datetime = "";
        int count = 1;
        for (int i = 0; i < list.size(); i++) {
            String temp = list.get(i);
            StringTokenizer st;
            if (i == 0) {
                st = new StringTokenizer(temp, "-");
            } else {
                st = new StringTokenizer(temp, ":");
            }
            int k = st.countTokens();
            for (int j = 0; j < k; j++) {
                String sttemp = (String) st.nextElement();
                if (count == 1) {
                    datetime = sttemp;
                } else {
                    if ((sttemp.equals("0")) || (sttemp.equals("00"))) {
                        sttemp = "0";
                    } else if ((Integer.valueOf(sttemp).intValue()) < 10) {
                        sttemp = sttemp.replaceAll("0", "");
                    }
                    if (count < 4) {
                        if ((Integer.valueOf(sttemp).intValue()) < 10) {
                            datetime = datetime + "-0" + sttemp;
                        } else {
                            datetime = datetime + "-" + sttemp;
                        }
                    }
                    if (count == 4) {
                        if ((Integer.valueOf(sttemp).intValue()) < 10) {
                            datetime = datetime + " 0" + sttemp;
                        } else {
                            datetime = datetime + " " + sttemp;
                        }
                    }
                    if (count > 4) {
                        if ((Integer.valueOf(sttemp).intValue()) < 10) {
                            datetime = datetime + ":0" + sttemp;
                        } else {
                            datetime = datetime + ":" + sttemp;
                        }
                    }
                }
                count++;
            }
        }

        try {
            @SuppressWarnings("unused")
            Date test = getDateFromStr(datetime); // 测试能否格式化成时间
            return datetime;
        } catch (Exception e) {
            return "";
        }
    }

    /**
     * 把标准的2007-02-02 07:01:08格式转换成日期对象
     *
     * @param datetime 日期,标准的2007-02-02 07:01:08格式
     * @return 日期对象
     */
    @SuppressWarnings("deprecation")
    public static Date getDateFromStr(String datetime) {
        if (datetime == null || "".equals(datetime)) {
            return new Date();
        }

        String nyr = datetime.trim();

        if (nyr.indexOf(" ") > 0) {
            nyr = nyr.substring(0, nyr.indexOf(" "));
        } else {
            nyr = nyr;
        }

        StringTokenizer st = new StringTokenizer(nyr, "-");
        Date date = new Date();
        String temp = "";
        int count = st.countTokens();
        for (int i = 0; i < count; i++) {
            temp = (String) st.nextElement();
            // if(!(temp.equals("0")))
            // temp.replaceAll("0", "");
            if (i == 0) {
                date.setYear(Integer.parseInt(temp) - 1900);
            }
            if (i == 1) {
                date.setMonth(Integer.parseInt(temp) - 1);
            }
            if (i == 2) {
                date.setDate(Integer.parseInt(temp));
            }
        }

        if (datetime.length() > 10) {
            String sfm = datetime.substring(11, 19);
            StringTokenizer st2 = new StringTokenizer(sfm, ":");
            count = st2.countTokens();
            for (int i = 0; i < count; i++) {
                temp = (String) st2.nextElement();
                // if(!(temp.equals("0")))
                // temp.replaceAll("0", "");
                if (i == 0) {
                    date.setHours(Integer.parseInt(temp));
                }
                if (i == 1) {
                    date.setMinutes(Integer.parseInt(temp));
                }
                if (i == 2) {
                    date.setSeconds(Integer.parseInt(temp));
                }
            }
        }
        return date;
    }

    /**
     * 返回两个日期相差天数
     *
     * @param startDate 起始日期对象
     * @param endDate   截止日期对象
     * @return
     */
    public static int getQuot(Date startDate, Date endDate) {
        long quot = (endDate.getTime() - startDate.getTime()) / MILLISECONDS_A_DAY;
        return (int) quot;
    }

    /**
     * 返回两个日期相差天数
     *
     * @param startDateStr 起始日期字符串
     * @param endDateStr   截止期字符串
     * @param format       时间格式
     * @return
     */
    public static int getQuot(String startDateStr, String endDateStr,
                              String format) {
        long quot = 0;
        format = (format != null && format.length() > 0) ? format
                : DEFAULT_DATE_FORMAT;
        SimpleDateFormat ft = new SimpleDateFormat(format);
        try {
            Date date1 = ft.parse(endDateStr);
            Date date2 = ft.parse(startDateStr);
            quot = date1.getTime() - date2.getTime();
            quot = quot / MILLISECONDS_A_DAY;
        } catch (ParseException e) {
            logger.error("获取两个日期相差天数异常: ", e);
        }
        return (int) quot;
    }

    /**
     * 返回开始时间
     *
     * @param day        开始时间与截至时间相差的天数
     * @param endDateStr 截止期字符串
     * @param format     时间格式
     * @return
     */

    public static String getStartDateStr(Integer day, String endDateStr,
                                         String format) {
        long quot = 0;
        String startDateStr = null;
        format = (format != null && format.length() > 0) ? format
                : DEFAULT_DATE_FORMAT;
        SimpleDateFormat ft = new SimpleDateFormat(format);
        try {
            Date date1 = ft.parse(endDateStr);
            Long time = date1.getTime() - day * MILLISECONDS_A_DAY;
            Date date = new Date(time);
            startDateStr = ft.format(date);

        } catch (ParseException e) {
            logger.error("获取开始时间异常: ", e);
        }
        return startDateStr;
    }


    /**
     * 返回日期字符串："yyyy-MM-dd HH:mm" 格式。
     *
     * @param date
     * @return
     */
    public static final String getDateTime(Date date) {
        if (date == null) {
            return "";
        }
        DateFormat ymdhmsFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        return ymdhmsFormat.format(date);
    }

    /**
     * 按给定格式返回时间的字符串
     *
     * @param date
     * @param pattern
     * @return
     */
    public static final String getDateTime(Date date, String pattern) {
        if (date == null) {
            return "";
        }
        DateFormat ymdhmsFormat = new SimpleDateFormat(pattern);
        return ymdhmsFormat.format(date);
    }

    /**
     * 返回两个日期相差的小时
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static int getQuotHours(Date startDate, Date endDate) {
        long quot = 0;
        quot = endDate.getTime() - startDate.getTime();
        quot = quot / MILLISECONDS_A_HOUR;
        return (int) quot;
    }

    /**
     * 返回两个日期相差的秒数
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static int getQuotSeconds(Date startDate, Date endDate) {
        long quot = 0;
        quot = endDate.getTime() - startDate.getTime();
        quot = quot / MILLISECONDS_A_second;
        return (int) quot;
    }

    /**
     * 将字符串转换为日期型 格式为: yyyy-MM-dd
     *
     * @param dateTime
     * @return
     */
    public static Date getDateTime(String dateTime) {
        return getDateTime(dateTime, "yyyy-MM-dd");
    }

    /**
     * @param dateTime
     * @return
     * @Description: "yyyy-mm-dd hh24：mm:ss.fff";
     */
    public static Date getDate24Time(String dateTime) {
        return getDateTime(dateTime, DEFAULT_DATETIME24_FORMAT);
    }

    public static Date getDateTime(String dateTime, String formatPattern) {
        try {
            if (StringUtils.isNotBlank(dateTime)
                    && StringUtils.isNotBlank(formatPattern)) {
                SimpleDateFormat format = new SimpleDateFormat(formatPattern);
                return format.parse(dateTime);
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 将字符串转换为日期型 格式为: yyyy-MM-dd HH:mm:ss
     *
     * @param dateTime
     * @return
     */
    public static Date getDateDetailTime(String dateTime) {
        try {
            if (StringUtils.isNotBlank(dateTime)) {
                SimpleDateFormat format = new SimpleDateFormat(
                        "yyyy-MM-dd HH:mm:ss");

                return format.parse(dateTime);
            }
        } catch (ParseException e) {
            logger.error("解析日期失败", e);
        }

        return null;
    }

    /**
     * 取当前的时间戳，在页面上保证URL唯一，防止缓存
     *
     * @return
     */
    public static long getDtSeq() {
        return System.currentTimeMillis();
    }

    /**
     * 判断是否在参数日期的最大值和最小值之间
     *
     * @param min
     * @param compare
     * @return
     */
    public static boolean isBetween(Date min, Date compare) {
        Boolean ret = false;
        Date minDate = DateUtil.dateOnlyExt(min);
        Date maxDate = DateUtil.dateOnlyExt(DateUtil.addDays(min, 1));
        if (compare.after(minDate) && compare.before(maxDate)) {
            ret = true;
        }
        return ret;
    }

    /**
     * @param min
     * @param compare
     * @return
     * @Description: 比较2个时间的时间差
     */
    public static Long compare(Date min, Date compare) {
        return (compare.getTime() - min.getTime()) / 1000;
    }

    public static Date getDate(int year, int month, int day) {
        Calendar cal = Calendar.getInstance();
        cal.set(year, month - 1, day);
        return cal.getTime();
    }

    /**
     * 获取本月/上月/本季度的月初和月末.
     *
     * @param monthRange 取值范围{cm:本月，pm:上月，sm:本季度}
     * @return Map{firstDay:yyyy-MM-dd, lastDay:yyyy-MM-dd}
     */
    public static Map<String, String> getFLDayMap(String monthRange) {
        return getFLDayMap(monthRange, DEFAULT_DATE_FORMAT);
    }

    /**
     * 获取本月/上月/本季度的月初和月末.
     *
     * @param monthRange 取值范围{cm:本月，pm:上月，sm:本季度}
     * @param pattern
     * @return Map{firstDay:yyyy-MM-dd, lastDay:yyyy-MM-dd}
     */
    public static Map<String, String> getFLDayMap(String monthRange,
                                                  String pattern) {
        Map<String, String> rs = new LinkedHashMap<String, String>();

        SimpleDateFormat df = new SimpleDateFormat(pattern);
        GregorianCalendar calendar = new GregorianCalendar();
        calendar.setTime(new Date());

        if (StringUtils.isBlank(monthRange)) {
            monthRange = "cm";
        }

        if (!"sm".equals(monthRange)) {
            if ("pm".equals(monthRange)) {
                calendar.add(Calendar.MONTH, -1);
            }

            calendar.set(Calendar.DAY_OF_MONTH, 1);
            rs.put("firstDay", df.format(calendar.getTime()));

            calendar.set(Calendar.DAY_OF_MONTH,
                    calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
            rs.put("lastDay", df.format(calendar.getTime()));

            return rs;
        }

        /*
         * 本季度的月初和月末
         */
        int[][] seasons = {{1, 3}, // 春季
                {4, 6}, // 夏季
                {7, 9}, // 秋季
                {10, 12} // 冬季
        };
        int cm = calendar.get(Calendar.MONTH) + 1;

        for (int[] im : seasons) {
            if (cm >= im[0] && cm <= im[1]) {
                calendar.set(Calendar.MONTH, im[0] - 1);
                calendar.set(Calendar.DAY_OF_MONTH, 1);
                rs.put("firstDay", df.format(calendar.getTime()));

                calendar.set(Calendar.MONTH, im[1] - 1);
                calendar.set(Calendar.DAY_OF_MONTH,
                        calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
                rs.put("lastDay", df.format(calendar.getTime()));

                break;
            }
        }

        return rs;
    }

    /**
     * 获取某日期的年份字符串
     *
     * @param date
     * @return 字符串类型的年份
     */
    public static String getYearString(Date date) {
        return DateUtil.date(date, DEFAULT_YEAR_FORMAT);
    }

    /**
     * 获取某日期的年份数字
     *
     * @param date
     * @return 数字类型的年份
     */
    public static int getYearInteger(Date date) {
        return Integer.parseInt(DateUtil.date(date, DEFAULT_YEAR_FORMAT));
    }

    /**
     * 获取某日期的月份字符串
     *
     * @param date
     * @return
     */
    public static String getMonthString(Date date) {
        return DateUtil.date(date, DEFAULT_MONTH_FORMAT);
    }

    public static String getDayString(Date date) {
        return DateUtil.date(date, DEFAULT_Day_FORMAT);
    }


    /**
     * 获取某日期的月份数字
     *
     * @param date
     * @return 数字类型的月份
     */
    public static int getMonthInteger(Date date) {
        return Integer.parseInt(DateUtil.date(date, DEFAULT_MONTH_FORMAT));
    }

    /**
     * 取得当前月的的最后一天
     *
     * @param year
     * @param month
     * @return
     */
    public static Date getLastDayOfCurMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);// 年
        cal.set(Calendar.MONTH, month);// 月，因为Calendar里的月是从0开始，所以要减1
        cal.set(Calendar.DATE, 1);// 日，设为一号
        // cal.add(Calendar.MONTH, 1);// 月份加一，得到下个月的一号
        cal.add(Calendar.DATE, -1);// 下一个月减一为本月最后一天
        return cal.getTime();// 获得月末是几号
    }

    /**
     * 获得当前日期的月末
     *
     * @param date
     * @return
     */
    public static Date getLastDayOfCurMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DAY_OF_MONTH));// 日，设为一号
        return cal.getTime();// 获得月末是几号
    }

    /**
     * 取得当前月的的第一天
     *
     * @param year
     * @param month
     * @return
     */
    public static Date getFirstDayOfCurMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);// 年
        cal.set(Calendar.MONTH, month - 1);// 月，因为Calendar里的月是从0开始，所以要减1
        cal.set(Calendar.DATE, 1);// 日，设为一号
        // cal.add(Calendar.MONTH, 1);// 月份加一，得到下个月的一号
        cal.add(Calendar.DATE, 0);// 下一个月减一为本月最后一天
        return cal.getTime();// 获得月末是几号
    }

    /**
     * 获得当前日期的月初
     *
     * @param date
     * @return
     */
    public static Date getFirstDayOfCurMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DATE, 1);// 日，设为一号
        return cal.getTime();// 获得月末是几号
    }

    /** */
    /**
     * 取得某天所在周的第一天
     *
     * @param date
     * @return
     */
    public static Date getFirstDayOfWeek(Date date) {
        Calendar c = new GregorianCalendar();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.setTime(date);
        c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek());
        return c.getTime();
    }

    /** */
    /**
     * 取得某天所在周的最后一天
     *
     * @param date
     * @return
     */
    public static Date getLastDayOfWeek(Date date) {
        Calendar c = new GregorianCalendar();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.setTime(date);
        c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek() + 6);
        return c.getTime();
    }

    /**
     * 验证日期是否有效，有效日期范围1900-1-1到2099-12-31.
     */
    public static boolean isValidDate(String ds) {
        if (StringUtils.isBlank(ds))
            return false;
        return pattern.matcher(ds).matches();
    }

    /**
     * 验证日期是否有效，有效日期范围1900-1-1到2099-12-31.
     */
    public static boolean isValidDate(Date d) {
        if (d == null) {
            return false;
        }
        return pattern.matcher(date(d, DEFAULT_DATE_FORMAT)).matches();
    }

    /**
     * 根据年月得到当月的天数
     *
     * @param date(格式：yyyy-MM)
     * @return
     */
    public static int getActualDays(String date) {
        Calendar rightNow = Calendar.getInstance();
        SimpleDateFormat simpleDate = new SimpleDateFormat(YEAR_MONTH_FORMAT); //如果写成年月日的形式的话，要写小d，如："yyyy/MM/dd"
        try {
            rightNow.setTime(simpleDate.parse(date)); //要计算你想要的月份，改变这里即可
        } catch (ParseException e) {
            logger.error("解析日期失败", e);
        }
        int days = rightNow.getActualMaximum(Calendar.DAY_OF_MONTH);
        return days;
    }

    /**
     * 根据年月得到当月的天数组成的年月日格式yyyyMMdd
     *
     * @param date(格式：yyyy-MM)
     * @return
     */
    public static String getActualDate(String date) {
        StringBuffer sb = new StringBuffer(date);
        int days = getActualDays(date);

        return sb.append(days).toString().replaceAll("/", "");
    }

    /**
     * 根据年月得到日期为第一天的日期格式yyyyMM01
     *
     * @param date(格式：yyyy-MM)
     * @return
     */
    public static String getFirstDate(String date) {
        StringBuffer sb = new StringBuffer(date);
        int days = getActualDays(date);

        return sb.append(days).toString().replaceAll("/", "");
    }

    /**
     * 比较2个日期的前后
     *
     * @param date1
     * @param date2
     * @return -1代表第一个日期小，1代表第一个日期大，0代表两个日期相等
     * @Description: 比较2个时间的前后
     */
    public static int compareDate(Date date1, Date date2) {
        Date dt1 = dateOnlyExt(date1);
        Date dt2 = dateOnlyExt(date2);
        if (dt1.getTime() > dt2.getTime()) {
            return 1;
        } else if (dt1.getTime() < dt2.getTime()) {
            return -1;
        } else {
            return 0;
        }

//      Calendar c1=Calendar.getInstance();
//      Calendar c2=Calendar.getInstance();
//      c1.setTime(dt1);
//      c2.setTime(dt2);
//      int result=c1.compareTo(c2);
//      if(result==0) //c1等于c2
//          return 0;
//      else if(result<0)//c1小于c2
//          return -1;
//      else    //c1大于c2
//          return 1;
    }

    /**
     * @param pattern
     * @return
     * @Description: 获取当前日期
     */
    public static String getCurrentDate(String pattern) {
        return date(new Date(), pattern);
    }

    /**
     * @return
     * @Description: 获取当前日期
     */
    public static String getCurrentDate() {
        return getCurrentDate(DEFAULT_DATE_FORMAT);
    }

    /**
     * @return
     * @Description: 获取当前时间
     */
    public static String getCurrentDateTime() {
        return getCurrentDate(DEFAULT_DATETIME_FORMAT);
    }


    /**
     * @param dateTime 格式为"yyyyMM"的字符串
     * @return foreYearMonth 返回前一个月的日期(格式"yyyyMM")
     * @Description: 获取某一日期的前一个月的日期(只取年月 " yyyyMM ")
     */
    public static String getForeYearMonth(String dateTime) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
        String foreYearMonth = "";
        try {
            Date rtime = sdf.parse(dateTime);
            Calendar cal = Calendar.getInstance();
            cal.setTime(rtime);
            cal.add(Calendar.MONTH, -1);
            foreYearMonth = sdf.format(cal.getTime());
        } catch (ParseException e) {
            logger.error("日期计算异常", e);
        }
        return foreYearMonth;
    }

    /**
     * @param year 某一年 ("yyyy")
     * @return foreYear 其前一年
     * @Description: 获取某一年的前一年(" yyyy ")
     * @date 2017年5月6日 下午5:07:18
     */
    public static String getForeYear(String year) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
        String foreYear = "";
        try {
            Date rtime = sdf.parse(year);
            Calendar cal = Calendar.getInstance();
            cal.setTime(rtime);
            cal.add(Calendar.YEAR, -1);
            foreYear = sdf.format(cal.getTime());
        } catch (ParseException e) {
            logger.error("年份计算异常", e);
        }
        return foreYear;
    }

    /**
     * @param dateTime 格式("yyyyMMdd")
     * @return
     * @Description: 判断某个日期是否是这个月的最后一天
     */
    public static boolean getIsTheMonthEnd(String dateTime) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Date rtime = new Date();
        try {
            rtime = sdf.parse(dateTime);
        } catch (ParseException e) {
            logger.error("日期判断异常", e);
        }

        Calendar cal = Calendar.getInstance();
        cal.setTime(rtime);
        int monthLastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);//获取当前月最后一天的数字,如20
        int dateInMonth = cal.get(Calendar.DAY_OF_MONTH);//获取指定日期的当前月数字,如20
        return monthLastDay == dateInMonth;

    }

    /**
     * @param date 年月  如:201704
     * @return 返回某月的最后一天的日期值 如:20
     * @Description: 获取某月的最后一天的日期值 如:20
     */
    public static int getTheMonthEndDay(String date) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
        Date rtime = new Date();
        try {
            rtime = sdf.parse(date);
        } catch (ParseException e) {
            logger.error("日期格式化异常", e);
        }

        Calendar cal = Calendar.getInstance();
        cal.setTime(rtime);
        int monthLastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);//获取当前月最后一天的数字,如20

        return monthLastDay;
    }

    /**
     * @param date 年月 如:201704
     * @param pre  前缀 如:2017
     * @param back 后缀 如:日
     * @return 返回该月自定义数组
     * @Description: 根据年月生成该月的自定义数组
     */
    public static List<Object> getTheMonthDayList(String date, String pre, String back) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
        Date rtime = new Date();
        try {
            rtime = sdf.parse(date);
        } catch (ParseException e) {
            logger.error("日期格式化异常", e);
        }

        Calendar cal = Calendar.getInstance();
        cal.setTime(rtime);
        int monthLastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);//获取当前月最后一天的数字,如20
        List<Object> dateList = new ArrayList<Object>();
        for (int i = 1; i <= monthLastDay; i++) {
            String j = "";
            if (i < 10) {
                j = "0" + i;
            } else {
                j = "" + i;
            }
            dateList.add(pre + j + back);
        }
        return dateList;
    }


    /**
     * @param bit  集合大小
     * @param pre  数据前缀
     * @param back 数据后缀
     * @return
     * @Description: 获取自定义大小和样式的数据集合
     */
    public static List<Object> getTheAutoList(int bit, String pre, String back) {

        List<Object> dateList = new ArrayList<Object>();
        for (int i = 1; i <= bit; i++) {
            String j = "";
            if (i < 10) {
                j = "0" + i;
            } else {
                j = "" + i;
            }
            dateList.add(pre + j + back);
        }
        return dateList;
    }

    /**
     * @param year
     * @return 返回日期数组 格式为:yyyyMMdd
     * @Description: 获取当年的日期数组(格式yyyy)
     */
    public static List<Object> getTheYearDaysList(int year) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Calendar calBegin = Calendar.getInstance();

        Date dBegin = getYearFirstDay(year);// 获取指定年份的第一天
        calBegin.setTime(dBegin);// 使用给定的 Date 设置此 Calendar 的时间

        Date dEnd = getYearLastDay(year);//获取指定年份的最后一天

        List<Object> dateList = new ArrayList<Object>();
        dateList.add(sdf.format(dBegin));
        // 测试此日期是否在指定日期之后
        while (dEnd.after(calBegin.getTime())) {
            calBegin.add(Calendar.DAY_OF_MONTH, 1);
            dateList.add(sdf.format(calBegin.getTime()));
        }

        return dateList;

    }

    /**
     * @param year
     * @return
     * @Description: 获取某年第一天日期
     */
    public static Date getYearFirstDay(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        Date currYearFirst = calendar.getTime();
        return currYearFirst;
    }

    /**
     * @param year
     * @return
     * @Description: 获取某年最后一天日期
     */
    public static Date getYearLastDay(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        calendar.roll(Calendar.DAY_OF_YEAR, -1);
        Date currYearLast = calendar.getTime();

        return currYearLast;
    }

    /**
     * @param s s
     * @return
     * @throws ParseException
     * @Description: 获取Timestamp 时间对应格式化的时间字符串
     */
    public static String getTimestampStr(Timestamp s) throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat(DEFAULT_DATETIME_FORMAT);
        String dateStr = "";

        try {
            dateStr = format.format(s);
        } catch (Exception e) {
            logger.error("Timestamp日期格式化错误", e);
        }
        return dateStr;
    }


    /**
     * @param s
     * @param sf 格式 如:M月d日 HH:mm 或 yyyy年M月
     * @return
     * @Description: 根据Timestamp时间获取对应格式的时间字符串
     */
    public static String getFormatMonthDateTimeStr(Timestamp s, String sf) {
        SimpleDateFormat sdf = new SimpleDateFormat(DEFAULT_DATETIME_FORMAT);
        SimpleDateFormat sdfmdt = new SimpleDateFormat(sf);
        String returnString = null;
        try {
            String tsStr = getTimestampStr(s);
            Date datetime = sdf.parse(tsStr);
            //组装格式为:8月8日 08：20 或 2017年8月
            returnString = sdfmdt.format(datetime);
        } catch (Exception e) {
            logger.error("getFormatMonthDateTimeStr:日期格式化错误", e);
        }
        return returnString;
    }

    /**
     * @param dateTime
     * @param formatPattern
     * @return
     * @Description: 将时间字符串转为特定的格式
     */
    public static Date formatDateTime(String dateTime, String formatPattern) {
        try {
            if (StringUtils.isNotBlank(dateTime)
                    && StringUtils.isNotBlank(formatPattern)) {
                SimpleDateFormat format = new SimpleDateFormat(formatPattern);
                return format.parse(dateTime);
            }
        } catch (ParseException e) {
            logger.error("DateUtil::formatDateTime::字符串转日期对象异常", e);
        }

        return null;
    }

    /**
     * 获取格林尼日时间
     *
     * @return
     */
    public static Date getDate1970() {
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis(0);
        return c.getTime();
    }

    /**
     * 比较当前系统时间是否小于参数时间
     *
     * @param time yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static boolean systimteLtDateStr(String time) {
        boolean result = false;
        try {
            result = System.currentTimeMillis() < DateUtil.parseDateFromStr(time).getTime();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 比较当前系统时间是否大于参数时间
     *
     * @param time yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static boolean systimteGtDateStr(String time) {
        boolean result = false;
        try {
            result = System.currentTimeMillis() > DateUtil.parseDateFromStr(time).getTime();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 将"yyyy-MM-dd HH:mm:ss"字符串转换为"yyyyMMdd"字符串
     *
     * @param timeStr "yyyy-MM-dd HH:mm:ss"格式时间字符串
     * @return "yyyyMMdd"格式时间字符串
     */
    public static String dateTimeToDateFullDate(String timeStr) {
        String result = "";
        try {
            Date date = parseDateFromStr(timeStr);
            SimpleDateFormat yyyyMMdd = new SimpleDateFormat(DEFAULT_DATEFULLDATE_FORMAT);
            result = yyyyMMdd.format(date);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 将当前时间转换为"yyyyMMdd"字符串
     *
     * @return "yyyyMMdd"格式时间字符串
     */
    public static String nowToDateFullDate() {
        String result = "";
        try {

            SimpleDateFormat yyyyMMdd = new SimpleDateFormat(DEFAULT_DATEFULLDATE_FORMAT);
            result = yyyyMMdd.format(new Date());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 将日期字符串转换为 yyyy年MM月dd日
     *
     * @param time 日期字符串
     * @return 中文日期格式
     */
    public static String getReadTimeStr(String time) {
        String result = null;
        try {
            Date date = DateUtil.parseDateFromStr(time);
            String year = DateUtil.getYearString(date);
            String month = DateUtil.getMonthString(date);
            String day = DateUtil.getDayString(date);
            result = year + "年" + month + "月" + day + "日";
        } catch (ParseException e) {
            logger.error("DateUtil::getReadTimeStr::字符串转中文日期异常", e);
        }
        return result;
    }

    /**
     * 将日期字符串转换为 MM月dd日 HH:mm
     *
     * @param time 日期字符串
     * @return 中文日期格式
     */
    public static String getDayTimeStr(String time) {
        String result = null;
        try {
            Date date = DateUtil.parseDateFromStr(time);
            result = DateUtil.date(date, "MM月dd日 HH:mm");
        } catch (ParseException e) {
            logger.error("DateUtil::getReadTimeStr::字符串转中文日期异常", e);
        }
        return result;
    }

    /**
     * 将日期字符串转换为 MM月dd日
     *
     * @param time 日期字符串
     * @return 中文日期格式
     */
    public static String getDayStr(String time) {
        String result = null;
        try {
            Date date = DateUtil.parseDateFromStr(time);
            result = DateUtil.date(date, "MM月dd日");
        } catch (ParseException e) {
            logger.error("DateUtil::getDayStr::字符串转中文日期异常", e);
        }
        return result;
    }

    /**
     * 得到前几天的日期集合,包括当天
     *
     * @param day 天数
     * @return list
     */
    public static List<Date> getBeforeDayList(int day) {
        List<Date> list = new ArrayList<>();
        for (int i = day - 1; i >= 0; i--) {
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.DATE, -i);
            Date date = calendar.getTime();
            list.add(date);
        }
        return list;
    }

    /**
     * 获取指定日期的上周开始时间
     *
     * @param date 日期
     * @return list
     */
    public static Date getBeginDayOfLastWeek(Date date) {
        Calendar cal = Calendar.getInstance();
        if (date != null) {
            cal.setTime(date);
        }
        int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayofweek == 1) {
            dayofweek += 7;
        }
        cal.add(Calendar.DATE, 2 - dayofweek - 7);
        return getDayStartTime(cal.getTime());
    }

    /**
     * 得到上周的日期集合
     *
     * @return list
     */
    public static List<Date> getLastWeekList() {
        Date lastWeekOneDay = getBeginDayOfLastWeek(null);
        List<Date> list = new ArrayList<>();
        for (int i = 0; i < 7; i++) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(lastWeekOneDay);
            calendar.add(Calendar.DATE, i);
            Date date = calendar.getTime();
            list.add(date);
        }
        return list;
    }

    /**
     * 获取最近6个月，包括本月
     *
     * @param month 月数
     * @return list
     */
    public static List<Date> getBeforeMonthList(int month) {
        month = month - 1;
        List<Date> list = new ArrayList<>();
        for (int i = month; i >= 0; i--) {
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.MONTH, -i);
            if (i == month) {
                //设置第一个月为1号
                calendar.set(Calendar.DATE, 1);
            }
            Date date = calendar.getTime();
            list.add(date);
        }
        return list;
    }

    /**
     * 获取季度
     *
     * @return list
     */
    public static JSONArray getQuarterList(Date date) {
        JSONArray dateArray = new JSONArray();
        JSONObject jsonObject = new JSONObject();
        Calendar calendar = Calendar.getInstance();
        if (date != null) {
            calendar.setTime(date);
        }
        int year = calendar.get(Calendar.YEAR);
        Calendar c1 = Calendar.getInstance();
        c1.set(Calendar.YEAR, year);
        c1.set(Calendar.MONTH, Calendar.JANUARY);
        c1.set(Calendar.DATE, 1);
        Calendar c3 = Calendar.getInstance();
        c3.set(Calendar.YEAR, year);
        c3.set(Calendar.MONTH, Calendar.MARCH);
        c3.set(Calendar.DATE, c3.getActualMaximum(Calendar.DAY_OF_MONTH));
        jsonObject.put("startTime", getDefaultBGNTimeStr(c1.getTime()));
        jsonObject.put("endTime", getDefaultLastTimeStr(c3.getTime()));
        dateArray.add(jsonObject);

        Calendar c4 = Calendar.getInstance();
        c4.set(Calendar.YEAR, year);
        c4.set(Calendar.MONTH, Calendar.APRIL);
        c4.set(Calendar.DATE, 1);
        Calendar c6 = Calendar.getInstance();
        c6.set(Calendar.YEAR, year);
        c6.set(Calendar.MONTH, Calendar.JUNE);
        c6.set(Calendar.DATE, c6.getActualMaximum(Calendar.DAY_OF_MONTH));
        jsonObject = new JSONObject();
        jsonObject.put("startTime", getDefaultBGNTimeStr(c4.getTime()));
        jsonObject.put("endTime", getDefaultLastTimeStr(c6.getTime()));
        dateArray.add(jsonObject);

        Calendar c7 = Calendar.getInstance();
        c7.set(Calendar.YEAR, year);
        c7.set(Calendar.MONTH, Calendar.JULY);
        c7.set(Calendar.DATE, 1);
        Calendar c9 = Calendar.getInstance();
        c9.set(Calendar.YEAR, year);
        c9.set(Calendar.MONTH, Calendar.SEPTEMBER);
        c9.set(Calendar.DATE, c9.getActualMaximum(Calendar.DAY_OF_MONTH));
        jsonObject = new JSONObject();
        jsonObject.put("startTime", getDefaultBGNTimeStr(c7.getTime()));
        jsonObject.put("endTime", getDefaultLastTimeStr(c9.getTime()));
        dateArray.add(jsonObject);

        Calendar c10 = Calendar.getInstance();
        c10.set(Calendar.YEAR, year);
        c10.set(Calendar.MONTH, Calendar.OCTOBER);
        c10.set(Calendar.DATE, 1);
        Calendar c12 = Calendar.getInstance();
        c12.set(Calendar.YEAR, year);
        c12.set(Calendar.MONTH, Calendar.DECEMBER);
        c12.set(Calendar.DATE, c12.getActualMaximum(Calendar.DAY_OF_MONTH));
        jsonObject = new JSONObject();
        jsonObject.put("startTime", getDefaultBGNTimeStr(c10.getTime()));
        jsonObject.put("endTime", getDefaultLastTimeStr(c12.getTime()));
        dateArray.add(jsonObject);
        return dateArray;
    }

    /**
     * 获取传入日期所在年的第一天
     *
     * @param date 日期
     * @return date
     */
    public static Date getFirstDayDateOfYear(final Date date) {
        final Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        final int last = cal.getActualMinimum(Calendar.DAY_OF_YEAR);
        cal.set(Calendar.DAY_OF_YEAR, last);
        return cal.getTime();
    }

    /**
     * 获取传入日期所在年的最后一天
     *
     * @param date 日期
     * @return date
     */
    public static Date getLastDayOfYear(final Date date) {
        final Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        final int last = cal.getActualMaximum(Calendar.DAY_OF_YEAR);
        cal.set(Calendar.DAY_OF_YEAR, last);
        return cal.getTime();
    }

    /**
     * 得到前几周的日期集合,不包含本周
     *
     * @return list
     */
    public static List<Date> getLastWeekList(int num) {
        List<Date> list = new ArrayList<>();
        for (int i = num - 1; i >= 0; i--) {
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.WEEK_OF_MONTH, -i);
            Date date = calendar.getTime();
            list.add(date);
        }
        return list;
    }

    /**
     * @return String
     * @Description: 将时间转化想要的格式 的字符串
     */
    public static String getWantFormatStr(Date date, String wantFormat) {
        SimpleDateFormat format = new SimpleDateFormat(wantFormat);
        return format.format(date);
    }

    /**
     * 获取两个字符串日期相差的月数,日期格式为"yyyy-MM"
     *
     * @param str1
     * @param str2
     * @return
     */
    public static int getMonthSub(String str1, String str2) {
        String year1 = str1.substring(0, 4);
        int year11 = Integer.parseInt(year1);
        String year2 = str2.substring(0, 4);
        int year22 = Integer.parseInt(year2);
        String month1 = str1.substring(5, 7);
        int month11 = Integer.parseInt(month1);
        String month2 = str2.substring(5, 7);
        int month22 = Integer.parseInt(month2);
        int monthSub = 0;
        if (year11 == year22) {
            if (month11 == month22) {
                monthSub = 0;
            } else {
                monthSub = Math.abs(month22 - month11);
            }
        } else if (year11 > year22) {
            monthSub = (year11 - year22) * 12 + month11 - month22;

        } else if (year11 < year22) {
            monthSub = (year22 - year11) * 12 + month22 - month11;
        }
        return monthSub;
    }

    /**
     * 获取近几年的所有月份,包括本年
     *
     * @return list
     */
    public static List<Date> getMonthOfYearList(int num) {
        List<Date> list = new ArrayList<>();
        for (int i = num - 1; i >= 0; i--) {
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.YEAR, -i);
            int year = calendar.get(Calendar.YEAR);
            for (int j = 0; j < 12; j++) {
                Calendar c = Calendar.getInstance();
                c.set(Calendar.YEAR, year);
                c.set(Calendar.MONTH, j);
                //设置第一个月为1号
                c.set(Calendar.DATE, 1);
                if (i == 0 && j == 11) {
                    //设置最后一个月为月尾
                    c.set(Calendar.DATE, c.getActualMaximum(Calendar.DAY_OF_MONTH));
                }
                list.add(c.getTime());
            }
        }
        return list;
    }

    /**
     * 获取近几年的年份,包括本年
     *
     * @return list
     */
    public static List<Date> getYearList(int num) {
        List<Date> list = new ArrayList<>();
        for (int i = num - 1; i >= 0; i--) {
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.YEAR, -i);
            list.add(calendar.getTime());
        }
        return list;
    }


    /*
     * 获取当前年的1月到12月日期（年月）
     *
     * */
    public static List<String> getThisYearLastMonth() {
        List<String> list = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MONTH, 11);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM");
        String dateStr = simpleDateFormat.format(calendar.getTime());
        list.add(dateStr);
        for (int i = 1; i < 12; i++) {
            calendar.add(Calendar.MONTH, -1);
            dateStr = simpleDateFormat.format(calendar.getTime());
            list.add(dateStr);
        }
        Collections.reverse(list);
        return list;
    }

    /*
     * 获取去年1月到去年12月日期（年月）
     *
     * */
    public static List<String> getOldYearLastMonth() {
        List<String> list = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MONTH, 11);
        calendar.add(Calendar.YEAR, -1);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM");
        String dateStr = simpleDateFormat.format(calendar.getTime());
        list.add(dateStr);
        for (int i = 1; i < 12; i++) {
            calendar.add(Calendar.MONTH, -1);
            dateStr = simpleDateFormat.format(calendar.getTime());
            list.add(dateStr);

        }
        Collections.reverse(list);
        return list;
    }


    /*
     * 获取今年1月和12月的日期（年月）
     *
     * */
    public static Map<String, String> getRecentMonth() {
        Map<String, String> map = new HashMap<>(2);
        String startTime = "";
        String endTime = "";
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MONTH, 11);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM");
        endTime = simpleDateFormat.format(calendar.getTime());
        calendar.add(Calendar.MONTH, -11);
        startTime = simpleDateFormat.format(calendar.getTime());


        map.put("startTime", startTime);
        map.put("endTime", endTime);
        return map;
    }

    /*
     * 获取去年1月和去年12月的日期（年月）
     *
     * */
    public static Map<String, String> getOldRecentMonth() {
        Map<String, String> map = new HashMap<>(2);
        String startTime = "";
        String endTime = "";
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MONTH, 11);
        calendar.add(Calendar.YEAR, -1);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM");
        endTime = simpleDateFormat.format(calendar.getTime());
        calendar.add(Calendar.MONTH, -11);
        startTime = simpleDateFormat.format(calendar.getTime());


        map.put("startTime", startTime);
        map.put("endTime", endTime);
        return map;
    }

    /**
     * 获取两个时间字符串 相隔的天数
     *
     * @param date1  时间1
     * @param date2  时间2
     * @param format 格式
     * @return 天数
     */
    public static long differentDays(String date1, String date2, String format) {
        if (null == date1 || null == date2) {
            return -1;
        }
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern(format);

        LocalDate d1 = LocalDate.parse(date1, dtf);

        LocalDate d2 = LocalDate.parse(date2, dtf);

        return ChronoUnit.DAYS.between(d1, d2);
    }

    public static long differentDays(Date date1, Date date2) {
        if (null == date1 || null == date2) {
            return -1;
        }
        ZoneId zoneId = ZoneId.systemDefault();
        Instant instant = date1.toInstant();
        Instant instant2 = date2.toInstant();
        LocalDate localDate1 = instant.atZone(zoneId).toLocalDate();
        LocalDate localDate2 = instant2.atZone(zoneId).toLocalDate();

        return ChronoUnit.DAYS.between(localDate1, localDate2);
    }

    /**
     * 收集起始时间到结束时间之间所有的时间并以字符串集合方式返回
     *
     * @param timeStart
     * @param timeEnd
     * @return
     */
    public static List<String> collectLocalDates(String timeStart, String timeEnd) {
        return collectLocalDates(LocalDate.parse(timeStart), LocalDate.parse(timeEnd));
    }

    /**
     * 收集起始时间到结束时间之间所有的时间
     */
    public static List<String> collectLocalDates(LocalDate start, LocalDate end) {
        // 用起始时间作为流的源头，按照每次加一天的方式创建一个无限流
        return Stream.iterate(start, localDate -> localDate.plusDays(1))
                // 截断无限流，长度为起始时间和结束时间的差+1个
                .limit(ChronoUnit.DAYS.between(start, end) + 1)
                // 由于最后要的是字符串，所以map转换一下
                .map(LocalDate::toString)
                // 把流收集为List
                .collect(Collectors.toList());
    }

    /**
     * 收集起始时间到结束时间之间所有的时间和星期
     */
    public static JSONArray collectLocalDatesAndWeek(LocalDate startDate, LocalDate endDate) {
        long numOfDays = ChronoUnit.DAYS.between(startDate, endDate) + 1;

        List<LocalDate> localDates = Stream.iterate(startDate, date -> date.plusDays(1))
                .limit(numOfDays)
                .collect(Collectors.toList());

        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        JSONArray list = new JSONArray();
        for (LocalDate localDate : localDates) {
            DayOfWeek dayOfWeek = localDate.getDayOfWeek();
            String date = df.format(localDate);

            JSONObject jsonObject = new JSONObject();
            jsonObject.put("date", date);
            jsonObject.put("week", dayOfWeek.getValue());
            list.add(jsonObject);
        }
        return list;
    }

    /**
     * 将一天按 指定时间分割
     *
     * @param date     日期  yyyy-mm-dd
     * @param interval 时间间隔(单位：分钟)
     * @return list
     */
    public static List<String> getIntervalTimeList(String date, int interval) throws Exception {
        Date startDate = DateUtil.parseDate(date);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        startDate = calendar.getTime();
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        Date endDate = calendar.getTime();


        List<String> list = new ArrayList<>();
        while (startDate.getTime() <= endDate.getTime()) {
            list.add(DateUtil.getDefaultTimeStr(startDate));
            calendar.setTime(startDate);
            calendar.add(Calendar.MINUTE, interval);
            if (calendar.getTime().getTime() > endDate.getTime()) {
                if (!startDate.equals(endDate)) {
                    list.add(DateUtil.getDefaultTimeStr(endDate));
                }
                startDate = calendar.getTime();
            } else {
                startDate = calendar.getTime();
            }
        }
        return list;
    }

    /**
     * 获取两个日期时间时间差（毫秒）
     *
     * @param dateTime1 yyyy-MM-dd HH:mm:ss 小
     * @param dateTime2 yyyy-MM-dd HH:mm:ss 大
     * @return
     * @throws ParseException
     */
    public static long getDateDiff(String dateTime1, String dateTime2) throws ParseException {
        Date date1 = DateUtil.parseDateFromStr(dateTime1);
        Date date2 = DateUtil.parseDateFromStr(dateTime2);
        return date2.getTime() - date1.getTime();
    }

    /**
     * 获取当前日期是周几
     * 周一:1，周二:2，周三:3，周四:4，周五:5，周六:6，周日:0
     */
    public static int getWeekNum(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_WEEK) - 1;
    }

    /**
     * 获取两个日期之间的所有月份
     *
     * @param startDate yyyy-MM
     * @param endDate   yyyy-MM
     */
    public static List<String> getMonthsBetweenDates(String startDate, String endDate) {
        List<String> months = new ArrayList<>();

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
        YearMonth start = YearMonth.parse(startDate, formatter);
        YearMonth end = YearMonth.parse(endDate, formatter);

        while (!start.isAfter(end)) {
            months.add(start.toString());
            start = start.plusMonths(1);
        }

        return months;
    }

}